home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / jabber / filetransfer / socketserver.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  9KB  |  258 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from struct import unpack, pack
  5. from jabber.filetransfer.S5BFileXferHandler import SocketEventMixin
  6. import functools
  7. import common
  8. from socket import AF_INET, SOCK_STREAM
  9. import AsyncoreThread
  10. from hashlib import sha1
  11. from functools import partial
  12. from threading import RLock
  13. from util import lock, get_ips_s
  14. from logging import getLogger
  15. log = getLogger('jabber.filetransfer.s5bserver')
  16.  
  17. class ProxyFailure(StopIteration):
  18.     pass
  19.  
  20.  
  21. def this(f):
  22.     
  23.     def wrapper1(self, *args, **kw):
  24.         return f(self(), *args, **kw)
  25.  
  26.     wrapper1 = (functools.wraps(f),)(wrapper1)
  27.     return wrapper1
  28.  
  29.  
  30. class JabberS5BServerSocket(common.socket):
  31.     _this = None
  32.     started = False
  33.     _lock = RLock()
  34.     bind_addr = ('', 0)
  35.     waiting_hashs = []
  36.     connected_hashs = { }
  37.     
  38.     def __init__(self, addr = None):
  39.         if self() is None:
  40.             if addr is not None:
  41.                 type(self).bind_addr = ('', 0)
  42.             
  43.             common.socket.__init__(self, False)
  44.             type(self)._this = self
  45.         
  46.  
  47.     
  48.     def __call__(self):
  49.         return type(self)._this
  50.  
  51.     
  52.     def start(self):
  53.         if not self.started:
  54.             self.started = True
  55.             self.create_socket(AF_INET, SOCK_STREAM)
  56.             
  57.             try:
  58.                 self.bind(self.bind_addr)
  59.             except Exception:
  60.                 e = None
  61.                 self.log_info('failed to bind on (%r, %r)' % self.bind_addr)
  62.                 raise e
  63.  
  64.             self.listen(5)
  65.             AsyncoreThread.start()
  66.         
  67.  
  68.     start = this(lock(start))
  69.     
  70.     def stop(self):
  71.         if self.started:
  72.             self.started = False
  73.             self.close()
  74.         
  75.  
  76.     stop = this(lock(stop))
  77.     
  78.     def handle_accept(self):
  79.         log.info('handle_accept')
  80.         accepted = self.accept()
  81.         self.listen(5)
  82.         (connected_socket, address) = accepted
  83.         self._on_accept(connected_socket, address)
  84.  
  85.     
  86.     def _on_accept(self, sock, addr):
  87.         log.info('accept from (%r, %r)', sock, addr)
  88.         S5BIncomingSocket(sock, addr, self)
  89.  
  90.     
  91.     def conn_id(self, stream_id, initiator_jid, target_sid):
  92.         return sha1(stream_id + initiator_jid.as_unicode() + target_sid.as_unicode()).hexdigest()
  93.  
  94.     
  95.     def __del__(self):
  96.         self.stop()
  97.         superdel = getattr(common.socket, '__del__', None)
  98.         if superdel is not None:
  99.             superdel(self)
  100.         
  101.  
  102.     __del__ = this(__del__)
  103.     
  104.     def add_hash(self, hash):
  105.         log.info('adding hash: %s', hash)
  106.         self.waiting_hashs.append(hash)
  107.         if not self.started:
  108.             self.start()
  109.         
  110.  
  111.     add_hash = this(lock(add_hash))
  112.     
  113.     def hash_waiting(self, hash, conn):
  114.         log.info('waiting hash: %s', hash)
  115.         self.waiting_hashs.remove(hash)
  116.         if not self.waiting_hashs:
  117.             self.stop()
  118.         
  119.         self.connected_hashs[hash] = conn
  120.  
  121.     hash_waiting = this(lock(hash_waiting))
  122.     
  123.     def check_hash(self, hash):
  124.         return hash in self.connected_hashs
  125.  
  126.     check_hash = this(lock(check_hash))
  127.     
  128.     def retrieve_hash(self, hash):
  129.         log.info('retrieving hash: %s', hash)
  130.         if hash in self.connected_hashs:
  131.             return self.connected_hashs.pop(hash)
  132.         else:
  133.             
  134.             try:
  135.                 self.waiting_hashs.remove(hash)
  136.                 return False
  137.             except ValueError:
  138.                 return None
  139.             finally:
  140.                 if not self.waiting_hashs:
  141.                     self.stop()
  142.                 
  143.  
  144.  
  145.     retrieve_hash = this(lock(retrieve_hash))
  146.     
  147.     def hosts(self):
  148.         port = self.socket.getsockname()[1]
  149.         return [ (ip, port) for ip in get_ips_s() ]
  150.  
  151.     hosts = property(this(hosts))
  152.  
  153.  
  154. class S5BIncomingSocket(common.socket, SocketEventMixin):
  155.     
  156.     def __init__(self, sock, addr, server):
  157.         SocketEventMixin.__init__(self)
  158.         common.socket.__init__(self, sock)
  159.         self.server = server
  160.         self.data = None
  161.         self.proc(self.s5b_ok())
  162.  
  163.     
  164.     def s5b_ok(self):
  165.         yield (2, None)
  166.         greeting = None
  167.         (_head, num_authmethods) = unpack('BB', greeting)
  168.         yield (num_authmethods, '')
  169.         methods = None
  170.         authmethods = unpack('%dB' % num_authmethods, methods)
  171.         if 0 not in authmethods:
  172.             yield (0, pack('BB', 5, 255))
  173.             raise ProxyFailure('bad auth methods')
  174.         else:
  175.             yield (4, pack('BB', 5, 0))
  176.             auth = None
  177.         (_head, tcp, reserved, type_) = unpack('4B', auth)
  178.         if not (_head == 5) and tcp == 1 and reserved == 0 and type_ == 3:
  179.             raise ProxyFailure('bad address header')
  180.         
  181.         yield (1, '')
  182.         (len_,) = None(unpack, 'B')
  183.         yield (len_ + 2, '')
  184.         (addr, _port) = None(unpack, '%dsH' % len_)
  185.         self.hash = addr
  186.         if self.server.check_hash(self.hash):
  187.             raise ProxyFailure('hash already connected')
  188.         
  189.         
  190.         self.collect_incoming_data = lambda _data: pass
  191.         strng = pack('=4B%dpH' % (len_ + 1,), 5, 0, 0, 3, addr, 0)
  192.         yield (False, strng)
  193.  
  194.     
  195.     def proc(self, gen):
  196.         
  197.         try:
  198.             (to_read, out_bytes) = gen.send(self.data)
  199.         except ProxyFailure:
  200.             self.close()
  201.             return None
  202.         except StopIteration:
  203.             
  204.             try:
  205.                 self.handle_expt = self.post_connect_expt
  206.                 self.handle_error = self.post_connect_error
  207.                 self.handle_close = self.post_connect_close
  208.                 self.do_disconnect = self.post_connect_disconnect
  209.                 self.server.hash_waiting(self.hash, self)
  210.             except ValueError:
  211.                 self.close()
  212.  
  213.             return None
  214.  
  215.         bytes = str(out_bytes)
  216.         print 'out_bytes', out_bytes, 'bytes', bytes
  217.         if out_bytes:
  218.             self.push(bytes)
  219.         
  220.         self.data = ''
  221.         self.found_terminator = partial(self.proc, gen)
  222.         if to_read is False:
  223.             log.info('found to_read is False, generator exhausted')
  224.             
  225.             self.found_terminator = lambda : pass
  226.             
  227.             self.collect_incoming_data = lambda _data: pass
  228.             self.set_terminator(0)
  229.             
  230.             try:
  231.                 self.handle_expt = self.post_connect_expt
  232.                 self.handle_error = self.post_connect_error
  233.                 self.handle_close = self.post_connect_close
  234.                 self.do_disconnect = self.post_connect_disconnect
  235.                 self.server.hash_waiting(self.hash, self)
  236.             except ValueError:
  237.                 self.close()
  238.             except:
  239.                 None<EXCEPTION MATCH>ValueError
  240.             
  241.  
  242.         None<EXCEPTION MATCH>ValueError
  243.         if isinstance(to_read, int):
  244.             self.set_terminator(to_read)
  245.         else:
  246.             self.set_terminator(to_read._size())
  247.  
  248.     
  249.     def collect_incoming_data(self, data):
  250.         self.data += data
  251.  
  252.     
  253.     def __del__(self):
  254.         self.close()
  255.         common.socket.__del__(self)
  256.  
  257.  
  258.